package com.abocode.happybean.copy.support;

import com.abocode.happybean.copy.MethodMap;
import com.abocode.happybean.copy.StringUtils;
import com.esotericsoftware.reflectasm.MethodAccess;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

/**
 * @author guanxf
 */
public class AsmMethodMap implements MethodMap {
    public void putMethod(MethodAccess methodAccess, Object object) {
        synchronized (object.getClass()) {
            Field[] fields = object.getClass().getDeclaredFields();
            List<String> fieldList = new ArrayList<String>(fields.length);
            for (Field field : fields) {
                // 是否是私有的，是否是静态的
                if (Modifier.isPrivate(field.getModifiers())
                        && !Modifier.isStatic(field.getModifiers())) {
                    // 非公共私有变量
                    // 获取属性名称
                    String fieldName = StringUtils.capitalize(field.getName());
                    StringBuffer getKey = new StringBuffer(object.getClass().getName()).append(MethodMapKey.POINT_GET).append(fieldName);
                    StringBuffer setKey = new StringBuffer(object.getClass().getName()).append(MethodMapKey.POINT_SET).append(fieldName);
                    StringBuffer getMethodName = new StringBuffer(MethodMapKey.GET).append(fieldName);
                    StringBuffer setMethodName = new StringBuffer(MethodMapKey.SET).append(fieldName);
                    // 获取get方法的下标
                    int getIndex = methodAccess.getIndex(getMethodName.toString());
                    // 获取set方法的下标
                    int setIndex = methodAccess.getIndex(setMethodName.toString());
                    // 将类名get方法名，方法下标注册到map中
                    MethodMapKey.setMethodIndexMap(getKey.toString(), getIndex);
                    // 将类名set方法名，方法下标注册到map中
                    MethodMapKey.setMethodIndexMap(setKey.toString(), setIndex);
                    // 将属性名称放入集合里
                    fieldList.add(fieldName);
                }
            }
            // 将类名，属性名称注册到map中
            MethodMapKey.setFieldMap(object.getClass(), fieldList);
            MethodMapKey.setMethodMap(object.getClass(), methodAccess);
        }
    }
}
